<template>
  <div class="mark-exam-container">
    <!-- 页面标题 -->
    <div class="page-header">
      <div class="header-left">
        <el-button icon="ArrowLeft" @click="goBack" plain>返回</el-button>
        <h2>人工评卷</h2>
      </div>
    </div>

    <!-- 顶部搜索和筛选区域 -->
    <div class="filter-section">
      <el-input
        v-model="searchText"
        placeholder="搜索学生学号/姓名"
        class="search-input"
        :prefix-icon="Search"
        clearable
      />
      <el-select v-model="subjectFilter" placeholder="科目筛选" clearable class="filter-select">
        <el-option v-for="item in subjectOptions" :key="item" :label="item" :value="item" />
      </el-select>
      <el-select v-model="classFilter" placeholder="班级筛选" clearable class="filter-select">
        <el-option v-for="item in classOptions" :key="item" :label="item" :value="item" />
      </el-select>
      <el-button type="primary" :icon="Refresh" @click="fetchExamRecords">刷新</el-button>
    </div>

    <!-- 试卷列表 -->
    <el-card shadow="hover" class="table-card">
      <el-table
        v-loading="loading"
        :data="filteredRecords"
        border
        stripe
        style="width: 100%"
        @row-click="handleRowClick"
        :row-class-name="tableRowClassName"
        height="calc(100vh - 260px)"
      >
        <el-table-column prop="studentId" label="学号" min-width="120" sortable />
        <el-table-column prop="realName" label="姓名" min-width="100" />
        <el-table-column prop="examId" label="考试ID" min-width="80" sortable />
        <el-table-column prop="examName" label="考试名称" min-width="140" show-overflow-tooltip />
        <el-table-column prop="subject" label="科目" min-width="100" />
        <el-table-column prop="className" label="班级" min-width="120" show-overflow-tooltip />
        <el-table-column prop="objectiveScore" label="客观题得分" min-width="120" sortable />
        <el-table-column prop="subjectiveScore" label="主观题得分" min-width="120" sortable />
        <el-table-column prop="recordTotalScore" label="总分" min-width="80" sortable />
        <el-table-column prop="recordStatus" label="状态" min-width="100">
          <template #default="{ row }">
            <el-tag :type="getStatusType(row.recordStatus)" effect="light">{{ row.recordStatus }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="submitTime" label="提交时间" min-width="160" sortable>
          <template #default="{ row }">
            {{ formatDateTime(row.submitTime) }}
          </template>
        </el-table-column>
        <el-table-column label="操作" fixed="right" min-width="120">
          <template #default="{ row }">
            <el-button
              type="primary"
              link
              :disabled="isMarked(row)"
              @click.stop="openMarkDialog(row)"
            >
              批改
            </el-button>
          </template>
        </el-table-column>
      </el-table>

      <!-- 分页 -->
      <div class="pagination-container">
        <el-pagination
          v-model:current-page="currentPage"
          v-model:page-size="pageSize"
          :total="total"
          :page-sizes="[10, 20, 50, 100]"
          layout="total, sizes, prev, pager, next, jumper"
          background
        />
      </div>
    </el-card>

    <!-- 批改对话框 -->
    <el-dialog
      v-model="markDialogVisible"
      title="试卷批改"
      width="90%"
      destroy-on-close
      :close-on-click-modal="false"
      top="3vh"
      fullscreen
      class="mark-dialog"
    >
      <div v-if="currentRecord" class="mark-dialog-content">
        <div class="student-info-card">
          <el-descriptions :column="3" border size="medium">
            <el-descriptions-item label="学号">{{ currentRecord.studentId }}</el-descriptions-item>
            <el-descriptions-item label="姓名">{{ currentRecord.realName }}</el-descriptions-item>
            <el-descriptions-item label="班级">{{ currentRecord.className || '未分配' }}</el-descriptions-item>
            <el-descriptions-item label="考试名称">{{ currentRecord.examName }}</el-descriptions-item>
            <el-descriptions-item label="科目">{{ currentRecord.subject }}</el-descriptions-item>
            <el-descriptions-item label="客观题得分">
              <span class="score-value">{{ currentRecord.objectiveScore }}</span>
            </el-descriptions-item>
          </el-descriptions>
        </div>

        <div class="mark-summary" v-if="subjectiveAnswers.length">
          <div class="summary-title">
            <span>主观题批改情况</span>
            <span class="total-subjective">共 {{ subjectiveAnswers.length }} 道主观题</span>
          </div>
          <el-progress 
            :percentage="markingProgress" 
            :status="markingProgress === 100 ? 'success' : ''" 
            :stroke-width="15"
            class="marking-progress"
          />
        </div>

        <div class="subjective-questions" v-if="subjectiveAnswers.length">
          <div
            v-for="(answer, index) in subjectiveAnswers"
            :key="answer.answerId || answer.id"
            class="question-item"
          >
            <div class="question-header">
              <h3>第 {{ index + 1 }} 题（主观题）</h3>
              <span class="total-score">满分：{{ answer.questionScore || answer.score }}分</span>
            </div>
            
            <div class="question-content">
              <p class="question-text">{{ answer.questionContent || answer.content }}</p>
              <div class="answer-section">
                <div class="student-answer">
                  <h4>学生答案：</h4>
                  <div class="answer-content">{{ answer.studentAnswer || answer.answer || '未作答' }}</div>
                </div>
                <div class="reference-answer">
                  <h4>参考答案：</h4>
                  <div class="answer-content">{{ answer.correctAnswer || answer.standardAnswer }}</div>
                </div>
              </div>
              <div class="score-input">
                <div class="score-form">
                  <span class="score-label">得分：</span>
                  <el-input-number
                    v-model="answer.score"
                    :min="0"
                    :max="answer.questionScore || answer.totalScore || answer.score"
                    :step="1"
                    controls-position="right"
                    @change="(val) => markQuestion(answer, val)"
                  />
                  <span class="score-max">/ {{ answer.questionScore || answer.totalScore || answer.score }}分</span>
                </div>
                <div class="quick-score">
                  <el-button size="small" @click="markQuestion(answer, 0)">0分</el-button>
                  <el-button size="small" @click="markQuestion(answer, Math.floor((answer.questionScore || answer.totalScore || answer.score) / 2))">半分</el-button>
                  <el-button size="small" @click="markQuestion(answer, (answer.questionScore || answer.totalScore || answer.score))">满分</el-button>
                </div>
              </div>
            </div>
          </div>
        </div>

        <div v-else class="no-subjective">
          <el-empty description="该试卷没有需要批改的主观题" />
          <div class="empty-actions">
            <el-button type="primary" @click="submitNoSubjectiveMarking" size="large" :loading="submitting">确认批改</el-button>
          </div>
        </div>
      </div>

      <!-- 底部操作按钮，添加额外的空间 -->
      <div class="dialog-bottom-space"></div>

      <template #footer>
        <span class="dialog-footer" v-if="subjectiveAnswers.length > 0">
          <el-button @click="markDialogVisible = false" size="large">取消</el-button>
          <el-button type="primary" @click="submitMarking" :loading="submitting" size="large">
            提交批改
          </el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, computed, onMounted } from 'vue'
import { Search, Refresh, ArrowLeft } from '@element-plus/icons-vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import examApi from '@/api/exam'
import dayjs from 'dayjs'

// 数据
const loading = ref(false)
const searchText = ref('')
const currentPage = ref(1)
const pageSize = ref(10)
const total = ref(0)
const examRecords = ref([])
const markDialogVisible = ref(false)
const currentRecord = ref(null)
const subjectiveAnswers = ref([])
const submitting = ref(false)

// 筛选选项
const subjectFilter = ref('')
const classFilter = ref('')

// 计算筛选选项
const subjectOptions = computed(() => {
  const subjects = new Set()
  examRecords.value.forEach(record => {
    if (record.subject) subjects.add(record.subject)
  })
  return Array.from(subjects)
})

const classOptions = computed(() => {
  const classes = new Set()
  examRecords.value.forEach(record => {
    if (record.className) classes.add(record.className)
  })
  return Array.from(classes)
})

// 计算批改进度
const markingProgress = computed(() => {
  if (!subjectiveAnswers.value.length) return 0;
  
  const scoredQuestions = subjectiveAnswers.value.filter(answer => 
    answer.marked === true
  ).length;
  
  return Math.floor((scoredQuestions / subjectiveAnswers.value.length) * 100);
})

// 获取老师工号
const getTeacherId = () => {
  const userInfo = sessionStorage.getItem('userInfo')
  if (userInfo) {
    return JSON.parse(userInfo).schoolNumber
  }
  return ''
}

// 过滤后的记录
const filteredRecords = computed(() => {
  let filtered = examRecords.value

  // 搜索过滤
  if (searchText.value) {
    const searchValue = searchText.value.toLowerCase()
    filtered = filtered.filter(record =>
      record.studentId.toLowerCase().includes(searchValue) || 
      (record.realName && record.realName.toLowerCase().includes(searchValue))
    )
  }

  // 科目过滤
  if (subjectFilter.value) {
    filtered = filtered.filter(record => record.subject === subjectFilter.value)
  }

  // 班级过滤
  if (classFilter.value) {
    filtered = filtered.filter(record => record.className === classFilter.value)
  }

  total.value = filtered.length
  
  // 分页
  const start = (currentPage.value - 1) * pageSize.value
  const end = start + pageSize.value
  return filtered.slice(start, end)
})

// 获取考试记录
const fetchExamRecords = async () => {
  loading.value = true
  try {
    const teacherId = getTeacherId()
    if (!teacherId) {
      ElMessage.error('获取教师信息失败')
      return
    }
    
    const res = await examApi.getExamstudentAnswer(teacherId)
    if (res.code === 200) {
      examRecords.value = res.data
    } else {
      ElMessage.warning(res.message || '暂无考试记录')
      examRecords.value = []
    }
  } catch (error) {
    console.error('获取考试记录失败:', error)
    ElMessage.error('获取考试记录失败')
    examRecords.value = []
  } finally {
    loading.value = false
  }
}

// 行样式
const tableRowClassName = ({ row }) => {
  if (isMarked(row)) return 'marked-row'
  return ''
}

// 检查是否已批改
const isMarked = (row) => {
  return row.recordStatus === '已批改'
}

// 获取状态类型
const getStatusType = (status) => {
  const types = {
    '未批改': 'warning',
    '已批改': 'success',
    '批改中': 'info',
    '已提交': 'warning'  // 将"已提交"视为未批改状态
  }
  return types[status] || 'info'
}

// 格式化时间
const formatDateTime = (time) => {
  if (!time) return ''
  return dayjs(time).format('YYYY-MM-DD HH:mm:ss')
}

// 更新批改进度
const updateMarkingProgress = () => {
  // 批改进度由计算属性自动计算，此函数只用于触发视图更新
  // 实际上不需要做任何事，因为 Vue 3 的响应式系统会自动感知变化
}

// 标记题目是否已批改
const markQuestion = (answer, score) => {
  // 如果没有marked属性，添加该属性并标记为true
  answer.marked = true;
  answer.score = score;
  updateMarkingProgress();
}

// 打开批改对话框
const openMarkDialog = async (record) => {
  currentRecord.value = record
  markDialogVisible.value = true
  
  try {
    // 获取主观题答案
    const res = await examApi.getSubjectiveQuestion(record.examId, record.studentId)
    if (res.code === 200) {
      subjectiveAnswers.value = res.data.map(item => ({
        ...item,
        score: item.score || 0, // 确保每个题目都有初始分数
        marked: false // 初始状态为未批改
      }))
    } else {
      subjectiveAnswers.value = []
      ElMessage.warning(res.message || '没有找到需要批改的主观题')
    }
  } catch (error) {
    console.error('获取主观题答案失败:', error)
    ElMessage.error('获取主观题答案失败')
    subjectiveAnswers.value = []
  }
}

// 提交批改
const submitMarking = async () => {
  if (submitting.value) return
  if (!subjectiveAnswers.value.length) {
    markDialogVisible.value = false
    return
  }

  // 检查是否所有题目都已评分
  if (markingProgress.value < 100) {
    try {
      await ElMessageBox.confirm('还有未完成评分的题目，确定要提交吗？', '提示', {
        confirmButtonText: '确定提交',
        cancelButtonText: '继续批改',
        type: 'warning'
      })
    } catch (error) {
      // 用户选择继续批改
      return
    }
  }

  try {
    submitting.value = true
    
    // 获取已批改的题目
    const markedAnswers = subjectiveAnswers.value.filter(answer => answer.marked);
    
    if (markedAnswers.length === 0) {
      ElMessage.warning('请至少批改一道题目');
      submitting.value = false;
      return;
    }
    
    // 构造符合后端 SubjectiveAnswerDto 列表格式的数据
    const submitData = markedAnswers.map(answer => ({
      answerId: answer.answerId || answer.id,
      examId: currentRecord.value.examId,
      schoolNumber: currentRecord.value.studentId,
      questionId: answer.questionId || answer.id,
      score: answer.score
    }));
    
    // 调用更新考试状态接口
    const res = await examApi.updateExamStatus(submitData);
    
    if (res.code === 200) {
      ElMessage.success('批改成功');
      markDialogVisible.value = false;
      fetchExamRecords(); // 刷新列表
    } else {
      ElMessage.error(res.message || '批改失败');
    }
  } catch (error) {
    console.error('提交批改失败:', error);
    ElMessage.error('提交批改失败');
  } finally {
    submitting.value = false;
  }
}

// 行点击事件
const handleRowClick = (row) => {
  if (!isMarked(row)) {
    openMarkDialog(row)
  }
}

// 提交无主观题的批改结果
const submitNoSubjectiveMarking = async () => {
  if (submitting.value) return;
  
  try {
    submitting.value = true;
    
    // 确认是否要进行批改
    try {
      await ElMessageBox.confirm('确定要完成该试卷批改吗？', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'info'
      });
    } catch (error) {
      submitting.value = false;
      return;
    }
    
    // 确保examId是字符串类型
    const examId = String(currentRecord.value.examId);
    
    // 调用无主观题批改接口，只传递考试ID和学生ID
    const res = await examApi.updateExamStatusNull(
      examId, // 确保是字符串类型
      currentRecord.value.studentId
    );
    
    if (res.code === 200) {
      ElMessage.success('批改完成');
      markDialogVisible.value = false;
      fetchExamRecords(); // 刷新列表
    } else {
      ElMessage.error(res.message || '批改失败');
    }
  } catch (error) {
    console.error('提交批改失败:', error);
    ElMessage.error('提交批改失败');
  } finally {
    submitting.value = false;
  }
}

// 返回上一页
const goBack = () => {
  window.history.back();
}

// 初始化
onMounted(() => {
  fetchExamRecords()
})
</script>

<style scoped>
.mark-exam-container {
  padding: 20px;
  height: 100%;
}

.page-header {
  margin-bottom: 20px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.header-left {
  display: flex;
  align-items: center;
  gap: 15px;
}

.page-header h2 {
  margin: 0;
  font-size: 24px;
  color: #303133;
}

.filter-section {
  display: flex;
  gap: 16px;
  margin-bottom: 20px;
  flex-wrap: wrap;
}

.search-input {
  width: 300px;
}

.filter-select {
  width: 180px;
}

.table-card {
  margin-bottom: 20px;
}

.pagination-container {
  margin-top: 20px;
  display: flex;
  justify-content: flex-end;
}

/* 行样式 */
:deep(.marked-row) {
  background-color: #f0f9eb;
}

.student-info-card {
  margin-bottom: 24px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  border-radius: 4px;
}

.score-value {
  font-weight: bold;
  color: #409eff;
}

.mark-summary {
  margin-bottom: 24px;
  padding: 16px;
  background-color: #f5f7fa;
  border-radius: 4px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}

.summary-title {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
  font-weight: bold;
}

.total-subjective {
  color: #606266;
  font-size: 14px;
}

.marking-progress {
  margin-top: 10px;
}

.mark-dialog-content {
  max-height: calc(94vh - 150px);
  overflow-y: auto;
  padding-right: 10px;
  padding-bottom: 30px;
}

.question-item {
  border: 1px solid #ebeef5;
  border-radius: 4px;
  padding: 16px;
  margin-bottom: 16px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
  background-color: #fff;
}

.question-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
  border-bottom: 1px solid #ebeef5;
  padding-bottom: 10px;
}

.question-header h3 {
  margin: 0;
  color: #303133;
  font-size: 18px;
}

.total-score {
  color: #f56c6c;
  font-weight: bold;
  font-size: 16px;
}

.question-content .question-text {
  font-size: 16px;
  color: #303133;
  margin-bottom: 16px;
  line-height: 1.5;
  background-color: #f5f7fa;
  padding: 10px;
  border-radius: 4px;
  border-left: 4px solid #409eff;
}

.answer-section {
  background-color: #f5f7fa;
  padding: 16px;
  border-radius: 4px;
  margin-bottom: 16px;
}

.answer-section h4 {
  margin: 0 0 8px 0;
  color: #606266;
  font-size: 14px;
}

.answer-content {
  white-space: pre-wrap;
  background-color: #fff;
  padding: 10px;
  border-radius: 4px;
  min-height: 60px;
  border: 1px solid #dcdfe6;
}

.student-answer {
  margin-bottom: 16px;
}

.score-input {
  display: flex;
  flex-direction: column;
  gap: 12px;
  background-color: #fff;
  padding: 16px;
  border-radius: 4px;
  border: 1px solid #ebeef5;
}

.score-form {
  display: flex;
  align-items: center;
}

.score-label {
  margin-right: 10px;
  font-weight: bold;
}

.score-max {
  margin-left: 10px;
  color: #606266;
}

.quick-score {
  display: flex;
  gap: 10px;
}

.no-subjective {
  text-align: center;
  color: #909399;
  padding: 32px 32px 60px;
}

.empty-actions {
  margin-top: 30px;
  display: flex;
  justify-content: center;
}

.empty-actions .el-button {
  padding: 12px 30px;
  font-size: 16px;
}

@media (max-width: 768px) {
  .filter-section {
    flex-direction: column;
  }
  
  .search-input,
  .filter-select {
    width: 100%;
  }
}

.dialog-bottom-space {
  height: 25px;
}

.dialog-footer {
  display: flex;
  justify-content: center;
  padding: 20px 0 30px;
  gap: 20px;
}

.dialog-footer .el-button {
  min-width: 120px;
  height: 40px;
  font-size: 16px;
}

.mark-dialog {
  :deep(.el-dialog__body) {
    padding-bottom: 40px;
  }
  
  :deep(.el-dialog__footer) {
    padding-top: 20px;
    padding-bottom: 30px;
    border-top: 1px solid #f0f0f0;
  }
}
</style>
